package com.yuntsg.nnsfcp.service.front.ext;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yuntsg.nnsfcp.entity.ParseEntity;
import com.yuntsg.nnsfcp.front.entity.OrderBaseInfo;
import com.yuntsg.nnsfcp.front.entity.ParsingTxt;
import com.yuntsg.nnsfcp.front.entity.Wosdetail;
import com.yuntsg.nnsfcp.service.front.AbstractCalculateCite;
import com.yuntsg.nnsfcp.service.front.pojo.QueryScopeDetail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * SCIE 数据库计算被引
 *
 * @author ：ljx
 * @date ：Created in 2019/7/3
 */
@Slf4j
@Service
public class ScieCalculateCite extends AbstractCalculateCite implements Serializable {

    /**
     * 计算被引
     *
     * @param wosDetail 本地wos
     * @param boo       true 计算wos的全部被引, false不计算全部被引
     */
    @Override
    public void runCalculateCite(Wosdetail wosDetail, boolean boo) {
        List<Integer> fids = searchFileServiceImpl.getFids();

        //默认查全部
        List<ParsingTxt> txtList = parsingTxtMapper.selectList(new QueryWrapper<ParsingTxt>()
                .in("file_id", fids)
                .orderByAsc("PY"));

        //--------判断用户选择的被引计算时间------------
        OrderBaseInfo orderBaseInfo
                = orderBaseInfoMapper.selectOne(new QueryWrapper<OrderBaseInfo>()
                .eq("apply_id", wosDetail.getCommissionid()));
        QueryScopeDetail entity = orderService.queryScopeMap(orderBaseInfo);
        if (entity != null) {
            //判断当前文章的被因年是否达到 近5年的选择
            Integer txtStartYear = null;
            Integer txtEndYear = null;
            if (txtList.size() > 0) {
                //当前文章的所有被引次数中找到最小年
                ParsingTxt parsingTxt = txtList.get(0);
                if (parsingTxt != null) {
                    txtStartYear = parsingTxt.getPy();
                    if (txtStartYear == null) {
                        parsingTxt = txtList.get(1);
                        if (parsingTxt != null) {
                            txtStartYear = parsingTxt.getPy();
                        }
                    }
                    System.out.println("======小年:" + txtStartYear + "=======");
                }
                //当前文章的所有被引次数中找到最大年
                parsingTxt = txtList.get(txtList.size() - 1);
                if (parsingTxt != null) {
                    // TODO 年有空指针, 查询另一个字段好像是 ea ? 处理过cp别的代码
                    txtEndYear = parsingTxt.getPy();
                    System.out.println("======大年:" + txtEndYear + "=======");
                }
            }
            Integer excludeYear = entity.getExcludeYear();
            String excludeEndYear = entity.getExcludeEndYear();
            String startYear = entity.getExcludeStartYear();

            if (startYear != null && excludeEndYear != null) {
                Integer userStartYear = Integer.valueOf(startYear);
                Integer userEndYear = Integer.valueOf(excludeEndYear);
                //判断用户输入的最大年是否超过了 文章的最大年
                if (txtEndYear <= userEndYear) {
                    QueryWrapper<ParsingTxt> qw = new QueryWrapper<>();
                    qw.eq("file_id", fids);
                    qw.and(i -> i.between("PY", userStartYear, userEndYear));
                    qw.orderByAsc("PY");
                }
            } else if (excludeYear != null) {
                if (excludeYear == 1) {
                    final Integer txtEndYear2 = txtEndYear;
                    final Integer txtStartYear2 = txtStartYear;
                    txtList = parsingTxtMapper.selectList(new QueryWrapper<ParsingTxt>()
                            .eq("file_id", fids)
                            .and(i -> i.between("PY", txtEndYear2, txtStartYear2))
                            .orderByAsc("PY"));
                }
            }
        }

        if (txtList.size() > 0) {
            log.info("被引次数计算中..");
            String citationStatus = orderBaseInfo.getCitationStatus();
            //自己名字的9种格式
            String authorNameEn = orderBaseInfo.getAuthorNameEn();
            String[] userAuthorArr = authorNameEn.split(";");

            //作者的三种排除方式
            if (citationStatus != null && (!"".equals(citationStatus))) {
                //1:排除作者本人外(默认),
                if ("1".equals(citationStatus)) {
                    log.info("1:排除作者本人外");
                    selfCite = 0;
                    totleList = new ArrayList<>();
                    selfCiteList = new ArrayList<>();
                    citedList = new ArrayList<>();
                    wosQuoteList = new ArrayList<>();

                    for (int i = 0; i < txtList.size(); i++) {
                        ParsingTxt parsingTxt = txtList.get(i);
                        String[] auSplit = new String[0];
                        if (parsingTxt.getAu() != null) {
                            String au = parsingTxt.getAu().replace(" ", "").toLowerCase().trim();
                            auSplit = au.split(";");
                        }
                        String[] afSplit = new String[0];
                        if (parsingTxt.getAf() != null) {
                            String af = parsingTxt.getAf().replace(" ", "").toLowerCase().trim();
                            afSplit = af.split(";");
                        }
                        boolean auAf = false;
                        if (userAuthorArr.length > 0) {
                            for (int j = 0; j < userAuthorArr.length; j++) {
                                String userArr = userAuthorArr[j].replace(" ", "").toLowerCase().trim();
                                if (auSplit.length > 0) {
                                    //自引-匹配AU
                                    if (Arrays.asList(auSplit).contains(userArr)) {
                                        auAf = true;
                                        break;
                                    }
                                }
                                if (afSplit.length > 0) {
                                    //自引-匹配AF ;
                                    if (Arrays.asList(afSplit).contains(userArr)) {
                                        auAf = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (!boo) {
                            //是否计算全部的被引次数
                            ParseEntity parseEntity1 = addParse(parsingTxt);
                            totleList.add(parseEntity1);
                        }
                        //全称还是简称匹配到了加入自引列表
                        if (auAf) {
                            if (!boo) {
                                //包含则自引+1
                                selfCite += 1;
                                ParseEntity parseEntity = addParse(parsingTxt);
                                selfCiteList.add(parseEntity);
                            }
                        } else {
                            ParseEntity parseEntity = addParse(parsingTxt);
                            if (!boo) {
                                citedList.add(parseEntity);
                            } else {
                                //wos的总被引计算
                                wosQuoteList.add(parseEntity);
                            }
                        }
                    }
                }
                // 2:排除所有作者,
                else if ("2".equals(citationStatus)) {
                    log.info("2:排除所有作者");
                    totleList = new ArrayList<>();
                    eliminateAllList = new ArrayList<>();
                    wosQuoteList = new ArrayList<>();

                    //一篇文章的全部作者
                    String articleAuthor = wosDetail.getAuthor();
                    log.info("本篇文章的所有作者:" + articleAuthor);
                    if (articleAuthor != null && (!"".equals(articleAuthor))) {
                        for (int i = 0; i < txtList.size(); i++) {
                            ParsingTxt parsingTxt = txtList.get(i);
                            String[] auSplit = new String[0];
                            if (parsingTxt.getAu() != null) {
                                String au = parsingTxt.getAu()
                                        .toLowerCase()
                                        .replaceAll(" ", "")
                                        .replaceAll(",", "")
                                        .replaceAll("_", "")
                                        .replaceAll("-", "")
                                        .trim();
                                auSplit = au.split(";");
                            }
                            String[] afSplit = new String[0];
                            if (parsingTxt.getAf() != null) {
                                String af = parsingTxt.getAf()
                                        .toLowerCase()
                                        .replaceAll(" ", "")
                                        .replaceAll(",", "")
                                        .replaceAll("-", "")
                                        .replaceAll("_", "")
                                        .trim();
                                afSplit = af.split(";");
                            }

                            boolean auAf = false;
                            String[] authors = articleAuthor.split(";");
                            for (int j = 0; j < authors.length; j++) {
                                //自引-匹配AU
                                String author = authors[j];
                                author = author
                                        .toLowerCase()
                                        .replaceAll(",", "")
                                        .replaceAll("-", "")
                                        .replaceAll("_", "")
                                        .replaceAll(" ", "")
                                        .trim();

                                if (auSplit.length > 0) {
                                    if (Arrays.asList(auSplit).contains(author)) {
                                        auAf = true;
                                        break;
                                    }
                                }
                                if (afSplit.length > 0) {
                                    if (Arrays.asList(afSplit).contains(author)) {
                                        auAf = true;
                                        break;
                                    }
                                }
                            }
                            if (!boo) {
                                //添加总引列表
                                ParseEntity parseEntity1 = addParse(parsingTxt);
                                totleList.add(parseEntity1);
                            }
                            //排除当前文章中的所有作者外的他引
                            if (!auAf) {
                                ParseEntity parseEntity = addParse(parsingTxt);
                                if (!boo) {
                                    eliminateAllList.add(parseEntity);
                                } else {
                                    //wos的总被引计算
                                    wosQuoteList.add(parseEntity);
                                }
                            }
                        }
                    }
                }
                // 3:排除项目合作者
                else if ("3".equals(citationStatus)) {
                    log.info("3:排除项目合作者");
                    totleList = new ArrayList<>();
                    collaboratorsList = new ArrayList<>();
                    wosQuoteList = new ArrayList<>();

                    //1.得到文章中的全部作者
                    String author = wosDetail.getAuthor();
                    //2.得到用户输入的全部作u者
                    String userTeam = orderBaseInfo.getAuthorNameEn();
                    //3.比较,文章中是否包含用户输入的团队
                    if (author != null && userTeam != null) {
                        String[] authors = new String[0];
                        if (author.contains(";")) {
                            authors = author.toLowerCase().replace(" ", "").split(";");
                        } else {
                            authors = new String[]{""};
                        }
                        String[] userTeams = userTeam.toLowerCase().replace(" ", "").split(";");
                        wosDetail.setTeamAuthorCheck("0");
                        for (int i = 0; i < authors.length; i++) {
                            if (Arrays.asList(authors).contains(userTeams[i])) {
                                wosDetail.setTeamAuthorCheck("1");
                                break;
                            }
                        }

                        //排除项目合作者 开始..
                        //作者汇总/ 文章作者 + 用户团队/ (与文章作者做了去重)
                        StringBuilder authorBuilder = new StringBuilder();
                        authorBuilder.append(author);
                        if (author.contains(";")) {
                            String[] authorArr = author.split(";");
                            String[] uAuthorArr = userTeam.split(";");
                            for (String s : uAuthorArr) {
                                if (!Arrays.asList(authorArr).contains(s)) {
                                    authorBuilder.append(s).append(";");
                                }
                            }
                        } else {
                            String[] str = {author};
                            String[] uAuthorArr = userTeam.split(";");
                            for (String s : uAuthorArr) {
                                if (!Arrays.asList(str).contains(s)) {
                                    authorBuilder.append(s).append(";");
                                }
                            }
                        }
                        //转换数组, 转换小写, 去空格
                        String[] userTeamsBuilder = authorBuilder.toString().toLowerCase().replace(" ", "").split(";");
                        log.info("<团队模式&英>文章作者+用户团队作者: " + Arrays.toString(userTeamsBuilder));

                        //4.获取已下载的被引次数
                        for (ParsingTxt parsingTxt : txtList) {
                            String[] auSplit = new String[0];
                            if (parsingTxt.getAu() != null) {
                                String au = parsingTxt.getAu().toLowerCase().replace(" ", "").trim();
                                auSplit = au.split(";");
                            }
                            String[] afSplit = new String[0];
                            if (parsingTxt.getAf() != null) {
                                String af = parsingTxt.getAf().toLowerCase().replace(" ", "").trim();
                                afSplit = af.split(";");
                            }
                            boolean auAf = false;
                            if (userTeamsBuilder.length > 0) {
                                for (int j = 0; j < userTeamsBuilder.length; j++) {
                                    if (auSplit.length > 0 || afSplit.length > 0) {
                                        //自引-匹配AU
                                        if (Arrays.asList(auSplit).contains(userTeamsBuilder[j])) {
                                            auAf = true;
                                        }
                                        //自引-匹配AF
                                        else if (Arrays.asList(afSplit).contains(userTeamsBuilder[j])) {
                                            auAf = true;
                                        }
                                    }
                                }
                            }
                            if (!boo) {
                                //添加wos的总引列表
                                ParseEntity parseEntity1 = addParse(parsingTxt);
                                totleList.add(parseEntity1);
                            }
                            //全称还是简称匹配到了加入自引列表
                            if (!auAf) {
                                ParseEntity parseEntity = addParse(parsingTxt);
                                if (!boo) {
                                    collaboratorsList.add(parseEntity);
                                } else {
                                    //wos的总被引计算
                                    wosQuoteList.add(parseEntity);
                                }
                            }
                        }
                    }
                }

                if (boo) {
                    //wos的总被引次数
                    if (wosQuoteList != null && wosQuoteList.size() > 0) {
                        wosDetail.setWosCitedNum(txtList.size());
                        wosDetail.setWosHeCitedNum(wosQuoteList.size());
                        wosDetail.setWosHeCitedList(JSON.toJSONString(wosQuoteList));
                    }
                } else {
                    //总被引列表 & 总被引次数
                    if (totleList != null && totleList.size() > 0) {
                        wosDetail.setUserTotalQuoteNum(txtList.size());
                        wosDetail.setUserTotalQuoteList(JSON.toJSONString(totleList));
                    }
                    //排除文章中的所有作者
                    if (eliminateAllList != null && eliminateAllList.size() > 0) {
                        //列表
                        wosDetail.setEliminateAllList(JSON.toJSONString(eliminateAllList));
                        //次数
                        wosDetail.setEliminateAllNum(eliminateAllList.size());
                    }
                    //团队合作者外的他引
                    if (collaboratorsList != null && collaboratorsList.size() > 0) {
                        //合作者引用次数
                        wosDetail.setTeamNum(collaboratorsList.size());
                        //合作者列表
                        wosDetail.setTeamList(JSON.toJSONString(collaboratorsList));
                    }
                    //作者本人外的他引次数      //判断作者外的他引(总引 - 自引)== 默认勾选的
                    if (citedList != null && citedList.size() > 0) {
                        wosDetail.setOtherNum(txtList.size() - selfCite);
                        wosDetail.setOtherList(JSON.toJSONString(citedList));
                    }
                    //计算作者本人外的他引时, 列出的自引列表
                    if (selfCiteList != null && selfCiteList.size() > 0) {
                        wosDetail.setMyQuote(JSON.toJSONString(selfCiteList));
                    }
                }
                wosdetailMapper.updateById(wosDetail);
                log.info("计算完成");

                //删除所有计算过的记录.
                deleteCitedTxt(txtList);
            }
        } else {
            //删除所有计算过的记录.
            deleteCitedTxt(txtList);

            txtList = null;
            myHandlerException(wosDetail);
        }

        //删除所有计算过的记录.
        deleteCitedTxt(txtList);
    }

}
